#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>

/* 显示屏相关头文件*/
#include <linux/fb.h>
#include <sys/mman.h>

#include "lcd.h"
#include "armsdkerr.h"

INT4 lcdautooff()
{
    INT4 fd;
    fd = open("/dev/tty1", O_RDWR);
    write(fd, "\033[9;0]", 8);
    close(fd);
    return 0;
}

VOID lcd_show_pixel(UINT1 *fbmem, INT4 line_length, INT4 bpp, INT4 x, INT4 y, UINT4 color)
{
    UINT1 *p8 = (UINT1 *)(fbmem + y * line_length + x * bpp / 8);

    unsigned short *p16 = (unsigned short *)p8;
    UINT4 *p32 = (UINT4 *)p8;
    UINT4 red, green, blue;

    switch(bpp)
    {
        case 8:
            *p8 = (UINT1)(color & 0xf);
            break;
        case 16:
            red = (color >> 16) & 0xff;
            green = (color >> 8) & 0xff;
            blue = (color >> 0) & 0xff;
            *p16 = (unsigned short)(((red >> 3) << 11) | ((green >> 2) <<5) | ((blue >> 3) << 0));
            break;
        case 32:
            *p32 = color;
            break;
        default:
            printf("can not support %d bpp", bpp);
            break;
    }
}

INT4 lcdTest()
{
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    UINT4 *temp;
    UINT4 color;
    UINT1 *fbp = 0;
    INT4 fp = 0;
    INT4 x, y;

    fp = open("/dev/fb0", O_RDWR);
    if (fp < 0)
    {
        printf("Error : Can not open framebuffer device/n");
        return 1;
    }

    if (ioctl(fp, FBIOGET_FSCREENINFO, &finfo))
    {
        printf("Error reading fixed information/n");
        return 2;
    }

    if (ioctl(fp, FBIOGET_VSCREENINFO, &vinfo))
    {
        printf("Error reading variable information/n");
        return 3;
    }

    printf("The mem is :%d\n", finfo.smem_len);
    printf("The line_length is :%d\n", finfo.line_length);
    printf("The xres is :%d\n", vinfo.xres);
    printf("The yres is :%d\n", vinfo.yres);
    printf("bits_per_pixel is :%d\n", vinfo.bits_per_pixel);

    fbp =(UINT1 *) mmap (0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fp, 0);
    if ((INT4) fbp == -1)
    {
        printf ("Error: failed to map framebuffer device to memory./n");
        return 4;
    }

    /* 刷红色*/
    color = 0xff << 16;
    for (y = 0; y < vinfo.yres; y++)
    {
        for(x = 0; x < vinfo.xres; x++)
        {
            lcd_show_pixel(fbp, finfo.line_length, vinfo.bits_per_pixel, x, y, color);
        }
    }
    usleep(1000*2000);

    /* 刷绿色*/
    color = 0xff << 8;
    for (y = 0; y < vinfo.yres; y++)
    {
        for(x = 0; x < vinfo.xres; x++)
        {
            lcd_show_pixel(fbp, finfo.line_length, vinfo.bits_per_pixel, x, y, color);
        }
    }
    usleep(1000*2000);

    /* 刷蓝色*/
    color = 0xff;
    for (y = 0; y < vinfo.yres; y++)
    {
        for(x = 0; x < vinfo.xres; x++)
        {
            lcd_show_pixel(fbp, finfo.line_length, vinfo.bits_per_pixel, x, y, color);
        }
    }
    usleep(1000*2000);

#if 0
    /* 显示图片*/
    temp = (unsigned int *)test_picture;
    for (y = 0; y < vinfo.yres; y++)
    {
        for(x = 0; x < vinfo.xres; x++)
        {
            lcd_show_pixel(fbp, finfo.line_length, vinfo.bits_per_pixel, x, y, *temp);
            temp ++;
        }
    }
#endif

    munmap (fbp, finfo.smem_len); /* 解除映射*/

    close(fp);
    return 0;
}
